"""typing -类型提示支持"""


# 下面的函数接受并返回一个字符串，气注释如下
def greeting(name: str) -> str:
    return "Hello " + name


# 类型别名
"""通过将类型分配别名来定义类型别名， 在此实例中 ，Vector并且List[float]将被视为可互换的同义词"""


from typing import List
Vector = List[float]


def scale(scalar: float, vector: Vector) -> Vector:
    return [scalar * num for num in vector]


new_vector = scale(2.0, [1.0, -4.3, 5.4])
# print(new_vector)

"""类型别名对于简化复杂的类型签名很有用，例如:"""

from typing import Dict, Tuple, Sequence


ConnectionOptions = Dict[str, str]
Address = Tuple[str, int]
Server = Tuple[Address, ConnectionOptions]


def broadcast(message: str, servers: Sequence[Server]) -> None:
    pass


def broadcast_message(message: str, servers: Sequence[Tuple[Tuple[str, int], Dict[str, str]]]) -> None:
    pass

"""请注意，None作为类型提示是一种特殊情况，并由代替type(None)"""


# NEWTYPE
# 使用NewType()助手功能创建不同的类型

from typing import NewType


UserId = NewType("USerId", int)
some_id = UserId(123456)

# 静态类型检查器会将新类型视为原始类型的子类， 这有助于捕获逻辑错误


def get_user_name(user_id: UserId) -> str:
    pass


user_a = get_user_name(UserId(123456))
user_b = UserId(-1)


# 可回调
"""
期望使用特定签名的回调函数的框架可以使用来提示类型。Callable[[Arg1Type, ARg2Type], ReturnType]:
列如：
"""
from typing import Callable


def feeder(get_index_item: Callable[[], str]) -> None:
    pass


def async_query(on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]) -> None:
    pass

"""通过使用文字省略号代替类型提示中的参数列表，
可以声明可调用对象的返回的类型而无需指定调用签名。Callable[..., ReturnType]"""


# 泛型
"""由于无法以通用方式静态推断有关保存在容器中的对象的类型信息，
因此抽象基类已经扩展为支持预定，以表示容器元素的预期的类型。"""
"""泛型可以通过使用新的工厂来进行参数化， 该工厂称为TypeVar"""


from typing import Sequence, TypeVar


T = TypeVar("T")


def first(l: Sequence[T]) -> T:
    return l[0]


# 用户自定义泛型类型
"""用户定义的类可以定义为通用类"""
from typing import TypeVar, Generic
from logging import Logger


T = TypeVar("T")


class LoggedVar(Generic[T]):
    def __init__(self, value: T, name: str) -> None:
        self.name = name
        self.logger = Logger
        self.value = value

    def set(self, new: T) -> None:
        self.log("Set" + repr(self.value))
        self.value = new

    def get(self) -> T:
        self.log("Get" + repr(self.value))
        return self.value

    def log(self, message: str) -> None:
        self.logger.info(msg=("%s: %s" % (self.name, message)))


"""
Generic[T]作为基类定义该类LoggedVar采用单个类型参数T。这也可以T作为类主体中的类型有效， 
所述Generic基类使用一个元类定义__getitem__(), 使得LoggedVar[T]是作为一种类型的有效的：
"""
from typing import Iterable


def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None:
    for var in vars:
        var.set(0)


a = [LoggedVar(1,"one"),
     LoggedVar(2, "two"),
     LoggedVar(3, "three"),
     LoggedVar(4, "four"),
     LoggedVar(5, "five")]
# zero_all_vars(a)
# print(a)

"""泛型类型可以具有任意数量的类型变量， 并且类型变量可能受到约束"""
from typing import TypeVar, Generic

T = TypeVar("T")
S = TypeVar("S", int, str)


class StrangePair(Generic[T, S]):
    pass







































